
# Copyright (c) 2014, Franklin Brauning V.  All rights reserved.
# 
#    El desarrollo inicial de esta utilidad fue producido
#    por Franklin Brauning <brauningbar@gmail.com>
# 
#    Si consideras que este codigo puede serte util, eres libre
#    de usarlo a conveniencia, pero no olvides mantener la licencia
#    y dar credito al autor.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#   * Redistributions of source code must retain the above copyright notice, this
#     list of conditions and the following disclaimer.
# 
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions and the following disclaimer in the documentation
#     and/or other materials provided with the distribution.
# 
#   * Neither the name of the author nor the names of its contributors may
#     be used to endorse or promote products derived from this software without
#     specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from django.db import models
from .base import *

class modifiable(abstractmodel):
	''' provides model modificacion detection

	With this .save wont proceed if model is not actually modified.

	Use this to not touch database or store copies unnecessarily
	'''
	class Meta:
		abstract = True

	def __init__(self, *a, **kw):
		super(modifiable, self).__init__(*a, **kw)
		self.modified = False

	def __setattr__(self, name, value):
		if getattr(self, 'id', None):
			try:
				if name in self._meta.get_all_field_names() and \
				        hasattr(self,name) and getattr(self, name) == value:
					self.microtrace("modifiable.__setattr__:%s:skipping same value" % name)
					return
			except KeyError:
				# clases con esquemas __get__ y __set__ modificados.
				# En particular models.FileField falla en getattr
				# Probablemente ImageField tambien
				pass
			super().__setattr__('modified', True)
		super().__setattr__(name, value)

	def willsave(self):
		''' check if this model will actually perform .save '''
		return self.modified or not self.id

	def ensuremodified(self):
		''' force model to perform .save even if not actually
		modified
		'''
		self.modified = True

	def save(self, *a, **kw):
		''' save model only if it is actually modified (or non existent) '''
		if self.willsave():
			super(modifiable, self).save(*a, **kw)
			self.modified = False
		else:
			self.trace("modifiable.save:not saving unmodified model")

